using System;
using System.Runtime.InteropServices;
using RDPAddins.Common;

namespace Win32
{
    namespace WtsApi32
    {
        internal delegate ChannelReturnCodes VirtualChannelInitDelegate(ref IntPtr initHandle, [MarshalAs(UnmanagedType.LPArray)] ChannelDef[] channels, int channelCount, uint versionRequested, [MarshalAs(UnmanagedType.FunctionPtr)] ChannelInitEventDelegate channelInitEventProc);
        internal delegate ChannelReturnCodes VirtualChannelOpenDelegate(IntPtr initHandle, ref uint openHandle, [MarshalAs(UnmanagedType.LPStr)] string channelName, [MarshalAs(UnmanagedType.FunctionPtr)] ChannelOpenEventDelegate channelOpenEventProc);
        internal delegate ChannelReturnCodes VirtualChannelCloseDelegate(uint openHandle);
        internal delegate ChannelReturnCodes VirtualChannelWriteDelegate(uint openHandle, byte[] data, uint dataLength, IntPtr userData);

        internal delegate void ChannelInitEventDelegate(IntPtr initHandle, ChannelEvents initEvent, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] data, uint dataLength);
        internal delegate void ChannelOpenEventDelegate(uint openHandle, ChannelEvents openEvent, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=3)] byte [] data, uint dataLength, uint totalLength, ChannelFlags dataFlags);

        [StructLayout(LayoutKind.Sequential)]
        internal struct ChannelEntryPoints
        {
            public int Size;
            public int ProtocolVersion;
            [MarshalAs(UnmanagedType.FunctionPtr)]
            public VirtualChannelInitDelegate VirtualChannelInit;
            [MarshalAs(UnmanagedType.FunctionPtr)]
            public VirtualChannelOpenDelegate VirtualChannelOpen;
            [MarshalAs(UnmanagedType.FunctionPtr)]
            public VirtualChannelCloseDelegate VirtualChannelClose;
            [MarshalAs(UnmanagedType.FunctionPtr)]
            public VirtualChannelWriteDelegate VirtualChannelWrite;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        internal struct ChannelDef
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
            public string name;
            public ChannelOptions options;
            void asda()
            {
            }
        }

        internal enum ChannelEvents: uint
        {
            Initialized = 0,
            Connected = 1,
            V1Connected = 2,
            Disconnected = 3,
            Terminated = 4,
            DataRecived = 10,
            WriteComplete = 11,
            WriteCanceled = 12
        }

        [Flags]
        internal enum ChannelFlags
        {
            First = 0x01,
            Last = 0x02,
            Only = First | Last,
            Middle = 0,
            Fail = 0x100,
            ShowProtocol = 0x10,
            Suspend = 0x20,
            Resume = 0x40
        }

        internal enum ChannelReturnCodes
        {
            Ok = 0,
            AlreadyInitialized = 1,
            NotInitialized = 2,
            AlreadyConnected = 3,
            NotConnected = 4,
            TooManyChanels = 5,
            BadChannel = 6,
            BadChannelHandle = 7,
            NoBuffer = 8,
            BadInitHandle = 9,
            NotOpen = 10,
            BadProc = 11,
            NoMemory = 12,
            UnknownChannelName = 13,
            AlreadyOpen = 14,
            NotInVirtualchannelEntry = 15,
            NullData = 16,
            ZeroLength = 17
        }
    }
}